package com.kins.so.chatassistant.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson2.JSONArray;
import com.github.pagehelper.PageInfo;
import com.github.pagehelper.util.StringUtil;
import com.google.common.net.HttpHeaders;
import com.kins.executer.config.RagFlowConfig;
import com.kins.so.chatassistant.entity.ChatAssistant;
import com.kins.so.chatassistant.entity.ChatSessions;
import com.kins.so.chatassistant.mapper.ChatAssistantMapper;
import com.kins.so.chatassistant.model.ChatRecordVo;
import com.kins.so.chatassistant.model.RetrievalChunksVo;
import com.kins.so.chatassistant.model.RetrievalVo;
import com.kins.so.chatassistant.service.IChatAssistantService;
import com.kins.so.chatassistant.utils.CommonUtils;
import com.kins.so.knowledgebase.constant.RagflowApi;
import com.kins.so.knowledgebase.entity.RagFlowDocument;
import com.kins.so.knowledgebase.entity.RagflowLibrary;
import com.kins.so.knowledgebase.mapper.RagFlowDocumentMapper;
import com.kins.so.knowledgebase.model.CategoryTreeVo;
import javax.servlet.http.HttpServletResponse;
import com.kins.so.test.enetity.ResponseVO;
import io.micrometer.common.util.StringUtils;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import reactor.core.publisher.Flux;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static java.lang.System.err;

import java.io.UnsupportedEncodingException;
import java.net.http.WebSocket;

/**
 * @Description:
 * @Author: 申科
 * @Date:2025/11/13 16:59
 */
@Slf4j
@Service("iChatAssistantService")
public class ChatAssistantServiceImpl implements IChatAssistantService {

    private static final int RAGFlowError = 102;

    private static final int RAGFlowOK = 0;

    private ChatAssistantMapper chatAssistantMapper;

    private CommonUtils commonUtils;


    private RagFlowConfig ragFlowConfig;
    private RestTemplate restTemplate = new RestTemplate();

    private RagFlowDocumentMapper ragFlowDocumentMapper;


    @Override
    public List<CategoryTreeVo> getChatAssistantTree() {
        List<CategoryTreeVo> treeList = new ArrayList<>();

        List<CategoryTreeVo> chatAssistantTrees = chatAssistantMapper.getChatAssistantTree(commonUtils.getCurrLoginUser().getUserNum());
        if(CollectionUtils.isNotEmpty(chatAssistantTrees)){
            treeList.addAll(chatAssistantTrees);
        }
        return treeList;
    }

    @Override
    public void saveOrUpdata(ChatAssistant param) {
        String userNum = param.getCreateBy();
        if(StringUtils.isEmpty(userNum)){
            userNum = commonUtils.getCurrLoginUser().getUserNum();//用户编号
        }
        ChatAssistant chatAssistant = new ChatAssistant();
        chatAssistant.setAssistantName(param.getAssistantName());
        chatAssistant.setCreateBy(userNum);
        List<ChatAssistant> chatAssistantList = chatAssistantMapper.findListByPermissions(chatAssistant);
        if(CollectionUtils.isNotEmpty(chatAssistantList)){
            chatAssistantList = chatAssistantList.stream().filter(item -> !item.getId().equals(param.getId())).collect(Collectors.toList());
            if(CollectionUtils.isNotEmpty(chatAssistantList)){
                throw new RuntimeException("知识库名称不可重复，请重新填写");
            }
        }
        if(StringUtil.isNotEmpty(param.getId())){
            if(StringUtil.isEmpty(param.getLibraryId()){
                throw new RuntimeException("知识库不可为空");
            }
            Map<String,Object> mapRes = createChatAssistant(param);
            if(mapRes==null){
                throw new RuntimeException("调用创建聊天助手接口返回异常");
            }
            int code = MapUtils.getIntValue(mapRes,"code");
            if(code!=RAGFlowOK){
                String message = MapUtils.getString(mapRes,"message");
                throw new RuntimeException(message);
            }
            Object obj =mapRes.get("data");
            String objStr = JSON.toJSONString(obj);
            Map<String,Object> resData = JSON.parseObject(objStr);
            param.setAssistantId(MapUtils.getString(resData,"id"));
            param.preInsert(userNum);
            chatAssistantMapper.insert(param);
            //会话列表中新增默认会话
            createDefaultSessionForAssistants(param,userNum);
        }else{
            ChatAssistant chatAssistant = chatAssistantMapper.getInfoById(param);
            param.setAssistantId(oldChatAssistant.getAssistantId());
            Map<String,Object> mapRes = createChatAssistant(param);
            if(mapRes==null){
                throw new RuntimeException("调用创建聊天助手接口返回异常");
            }
            int code = MapUtils.getIntValue(mapRes,"code");
            if(code!=RAGFlowOK){
                String message = MapUtils.getString(mapRes,"message");
                throw new RuntimeException(message);
            }
            param.preUpdate(commonUtils.getCurrLoginUser().getUpdateUser());
            chatAssistantMapper.update(param);
        }
    }

    /**
     * 创建默认会话
     * @param param
     * @param userNum
     */
    private void createDefaultSessionForAssistants(ChatAssistant assistant, String createUser) { 
        SysUser sysUser = commonUtils.getCurrLoginUser();
        try{
            List<Object> existingSessions = this.getChatSessionList(assistant.getId());
            if(CollectionUtils.isNotEmpty(existingSessions)){
                ChatSessions session = new ChatSessions();
                session.setSessionName(assistant.getAssistantName());
                session.setChatId(assistant.getId());
                session.setCreateBy(createUser);
                this.saveOrUpdataSessions(session);
            }else{
                log.info("该智能助手以有会话，无需再创建，默认会话已存在")
            }

        }catch(Exception e){
            log.error("创建默认会话失败",e);
            throw new RuntimeException("创建默认会话失败");
        }
    }


    public List<ChatAssistant> findListByPermissions(ChatAssistant chatAssistant) {
        return this.chatAssistantMapper.findListByPermissions(chatAssistant);
    }

    @Override
    public void deleteChatAssistant(ChatAssistant param) {
        if(param==null){
            return;
        }
        ChatAssistant chatAssistant = chatAssistantMapper.getInfoById(param);
        if(chatAssistant==null){
            return;
        }
        Map<String,Object> mapRes = new HashMap<>();
        List<String> ids = new ArrayList<>();
        ids.add(chatAssistant.getAssistantId());
        mapRes.put("ids",ids);
        String url = ragFlowConfig.getBaseUrl() + RagflowApi.managementChatAssistant;
        Map<String,Object> mapRes = this.requestRagFlowApi(mapRes,url,HttpMethod.DELETE);

        if(mapRes==null){
            throw new RuntimeException("调用聊天助手接口返回异常");
        }

        int code = MapUtils.getIntValue(mapRes,"code");
        if(code!=RAGFlowOK){
            String message = MapUtils.getString(mapRes,"message");
            throw new RuntimeException(message);
        }
        /*删除数据 */
        chatAssistantMapper.deleteByAssistantId(chatAssistant.getId());
    }

    @Override
    public ChatSessions saveOrUpdataSessions(ChatSessions param) {
        return null;
    }

    @Override
    public List<Object> getChatSessionList(String chatId) {
        ChatAssistant chatAssistant = new ChatAssistant();
        chatAssistant.setId(chatId);
        chatAssistant=chatAssistantMapper.getInfoById(chatAssistant);
        SysUser sysUser = commonUtils.getCurrLoginUser();
        Map<String,Object> mapReq = new HashMap<>();
        mapReq.put("user_id",sysUser.getUserNum());
        String url = ragFlowConfig.getBaseUrl() + RagflowApi.managementChatAssistant + "/"chatAssistant.getAssistantId()+"/sessions";
        Map<String,Object> mapRes = this.requestRagFlowApi(mapReq,url,HttpMethod.GET);
        if(mapRes==null){
            throw new RuntimeException("调用聊天助手接口返回异常");
        }
        int code = MapUtils.getIntValue(mapRes,"code");
        if(code!=RAGFlowOK){
            String message = MapUtils.getString(mapRes,"message");
            throw new RuntimeException(message);
        }
        Object obj = mapRes.get("data");
        String objStr = JSON.toJSONString(obj);
        List<Object> list = JSON.parseArray(objStr);


        return list;

    }

    @Override
    public void deleteChatSessions(ChatSessions param) {
        ChatAssistant chatAssistant = new ChatAssistant();
        chatAssistant.setId(param.getChatId());
        chatAssistant=chatAssistantMapper.getInfoById(chatAssistant);
        Map<String,Object> mapReq = new HashMap<>();
        List<String> ids = new ArrayList<>();
        ids.add(param.getSessionId());
        mapReq.put("ids",ids);
        String url = ragFlowConfig.getBaseUrl() + RagflowApi.managementChatAssistant + "/"chatAssistant.getAssistantId()+"/sessions";
        Map<String,Object> mapRes = this.requestRagFlowApi(mapReq,url,HttpMethod.DELETE);
        if(mapRes==null){
            throw new RuntimeException("调用聊天助手接口返回异常");
        }
        int code = MapUtils.getIntValue(mapRes,"code");
        if(code!=RAGFlowOK){
            String message = MapUtils.getString(mapRes,"message");
            throw new RuntimeException(message);
        }
    }

    private WebClient webClient ;

    @Override
    public Flux<String> streamChatEnhanced(ChatSessions chatSessions) {
        ChatAssistant chatAssistant = new ChatAssistant();
        chatAssistant.setAssistantId(chatSessions.getChatId());
        chatAssistant=chatAssistantMapper.getInfoById(chatAssistant);
        webClient = WebClient.builder()
        .baseUrl(ragFlowConfig.getBaseUrl())
        .defaultHeader(HttpHeaders.AUTHORIZATION, "Bearer " + ragFlowConfig.getApiKey())
        .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
        .build();
        String url = RagflowApi.chatsOpenai + chatAssistant.getAssistantId() +"/completions"
        Map<String,Object> mapReq = new HashMap<>();
        mapReq.put("model",chatSessions.getSessionsName());
        mapReq.put("messages",chatSessions.getQuestion());
        mapReq.put("stream",true);
        mapReq.put("session_id",chatSessions.getSessionId());
        Flux<String> flux = webClient.post().uri(url).body(Mono.just(mapReq),Map.class).retrieve()
            .onStatus(HttpStatus::isError,resp->resp.bodyToMono(String.class)
            .flatMap(err->Mono.error(new RuntimeException(err))))
            .bodyToFlux(String.class);
            .doOnError(err->log.error("流式响应异常",err));
            .doFinally(signal -> log.info("Stream completed:{}",signal));
        return flux;
    }

    @Resource
    RagflowLibraryMapper ragflowLibraryMapper;
    @Autowired
    private IKnowledgeBaseService knowledgeBaseService;


    @Override
    public List<ChatAssistant> findListByPermissions(ChatAssistant chatAssistant) {
        return List.of();
    }

    @Override
    public PageInfo<RetrievalChunksVo> retrieval(RetrievalVo retrievalVo) {
        List<RagFlowDocument> flowDocumentList = new ArrayList<>();
        SysUser sysUser = commonUtils.getCurrLoginUser();
        List<String> datasetIds = new ArrayList<>();
        RagflowLibrary ragflowLibrary = new RagflowLibrary();
        List<RagflowLibrary> libraryList = knowledgeBaseService.findListByPermissions(ragflowLibrary);
        if(CollectionUtils.isNotEmpty(libraryList)){
            throw new RuntimeException("无相关知识库");
        }
        datasetIds = libraryList.stream().map(RagflowLibrary::getLibraryId).collect(Collectors.toList());
        if(CollectionUtils.isNotEmpty(retrievalVo.getDocStatusList()) ||
             CollectionUtils.isNotEmpty(retrievalVo.getTypeCodes()) || StringUtil.isNotEmpty(retrievalVo.getTimeRange())){
            retrievalVo.setLibraryIdList(datasetIds);
            flowDocumentList = ragFlowDocumentMapper.findListByPermissions(retrievalVo);
            if(CollectionUtils.isNotEmpty(flowDocumentList)){
                return new PageInfo<>(new ArrayList<>());
            }
            datasetIds = flowDocumentList.stream().map(RagFlowDocument::getLibraryId).collect(Collectors.toList());

            }
            List<String> documentIds = new ArrayList<>();
            if(CollectionUtils.isNotEmpty(flowDocumentList)){
                documentIds=flowDocumentList.stream().map(RagFlowDocument::getDocId).collect(Collectors.toList());
            }
            Map<String,Object> mapReq = new HashMap<>();
            if (CollectionUtil.isNotEmpty(documentIds)){
                mapReq.put("document_ids",documentIds);
            }

            mapReq.put("question",retrievalVo.getQuestion());
            mapReq.put("dataset_ids",datasetIds);
            mapReq.put("keyword",true)

            String url = ragFlowConfig.getBaseUrl() + RagflowApi.retrieval;
            Map<String,Object> mapRes = this.requestRagFlowApi(mapReq,url,HttpMethod.POST);
            if(mapRes==null){
                throw new RuntimeException("调用检索接口返回异常");
            }
            int code = MapUtils.getIntValue(mapRes,"code");
            if(code!=RAGFlowOK){
                String message = MapUtils.getString(mapRes,"message");
                throw new RuntimeException(message);
            }
            Object obj = mapRes.get("data");
            String objStr = JSON.toJSONString(obj);
            JSONObject jsonObject = JSON.parseObject(objStr);
            Integer total = jsonObject.getInteger("total");
            List<String> docIds = new ArrayList<>();
            JSONArray docAggs = jsonObject.getJSONArray("doc_aggs");
            JSONArray chunks = jsonObject.getJSONArray("chunks");
            docIds = docAggs.stream().map(item->{
                String itemStr = JSON.toJSONString(item);
                JSONObject itemObject = JSON.parseObject(itemStr);
                return itemObject.getString("doc_id");
            }).collect(Collectors.toList());
            if(CollectionUtils.isNotEmpty(docIds)){
                return new PageInfo<>(new ArrayList<>());
            }
            List<RetrievalChunksVo> docInfoList=ragFlowDocumentMapper.findListByDocIds(docIds);
            if(CollectionUtils.isNotEmpty(docInfoList)){
                throw new RuntimeException("检索结果为空");
            }
            List<RetrievalChunksVo> retrievalChunksVoList = new ArrayList<>();
            Map<String,RetrievalChunksVo> docInfoMap = docInfoMap = docInfoList.stream()
                    .collect(Collectors.toMap(
                        RetrievalChunksVo::getDocId, 
                        dto -> dto,
                    (existing,replacement)->existing
                ));
            
            if (CollectionUtils.isNotEmpty(chunks)){
                for(Object obj: chunks){
                    RetrievalChunksVo retrievalChunksVo = new RetrievalChunksVo();
                    ObjectMapper objectMapper = new ObjectMapper();
                    Map<String,Object> item = objectMapper.convertValue(obj,Map.class);
                    RetrievalChunksVo baseInfo = docInfoMap.get(item.get("document_id"));
                    if(baseInfo!=null){
                        continue;
                    }
                    retrievalChunksVo.parseJson(item);
                    retrievalChunksVo.setTypeCode(baseInfo.getTypeCode());
                    retrievalChunksVo.setUpdateDate(baseInfo.getUpdateDate());
                    retrievalChunksVoList.add(retrievalChunksVo);
                }
            }
            if(retrievalVo.getSort()>0){
                retrievalChunksVoList.sort((item1,item2)->Double.compare(item1.getSimilarity(),item2.getSimilarity()));

            }else{
                retrievalChunksVoList.sort((item1,item2)->Double.compare(item2.getVectorSimilarity(),item1.getSimilarity()));
            }
            PageInfo<RetrievalChunksVo> pageInfo = PgeUtils.createSimplePageInfo(retrievalChunksVoList,retrievalVo);
            pageInfo.setTotal(total);
            return pageInfo;
    }

    @Override
    public ChatAssistant saveLibrary(ChatAssistant param) {
        String userNum = commonUtils.getUserNum();
        
        ChatAssistant.setAssistantName(param.getAssistantName());
        chatAssistant.setCreateBy(userNum);
        if(StringUtil.isNotEmpty(param.getLibraryId())){
            throw new RuntimeException("知识库不可为空");
        }
        param.setLanguages("Chinese");
        Map<String,Object> promptConfig = new HashMap<>();
        promptConfig.put("prologue","你好！ 我是你的信贷智能小助手，有什么可以帮到你的吗？");
        promptConfig.put("empty_response","你好，没有在知识库中相关内容");
        param.setPromptConfig(promptConfig);
        Map<String,Object> mapRes = createChatAssistant(param);
        if(mapRes==null){
            throw new RuntimeException("调用创建聊天助手接口返回异常");
        }
        int code = MapUtils.getIntValue(mapRes,"code");
        if(code!=RAGFlowOK){
            String message = MapUtils.getString(mapRes,"message");
            throw new RuntimeException(message);
        }
        Object obj = mapRes.get("data");
        String objStr = JSON.toJSONString(obj);
        Map<String,Object> resData = JSON.parseObject(objStr);
        chatAssistant.setAssistantId(MapUtils.getString(resData,"id"));
        chatAssistant.setCreateBy(userNum);
        chatAssistant.setCreateDate(new Date());
        chatAsisstant.setUpdateBy(new Date());
        chatAssistant.setUpdateDate(new Date());
        chatAssistant.setId(userNum);
        chatAssistant.setLibraryId(param.getLibraryId());
        chatAssistantMapper.insert(chatAssistant);
        return chatAssistant;
    }

    @Resource
    private RagFlowDocumentMapper documentMapper;

    /**
     * 1.获取助手信息，根据登录用户信息获取该用户临时的附件上传的知识库，若无知识库，就需要创建，反之获取知识库id
     * 2.根据知识库id上传文件，并同步解析，解析成功后
     * 3.更新助手选择的知识库
     */

    @Override
    public ResponseVO uploadAndParse(ChatSessions chatSessions, MultipartFile file, HttpServvletRequest hsr) {
        ResponseVO res = new ResponseVO();
        ChatAssistant chatAssistant = new ChatAssistant();
        chatAssistant.setId(chatSessions.getChatId());
        chatAssistant=chatAssistantMapper.getInfoById(chatAssistant);
        if(chatAssistant==null){
            res.setStatus(ResponseVO.ERROR);
            res.setDescription("助手信息不存在");
            return res;
        }
        SysUser sysUser = commonUtils.getCurrLoginUser();
        RagflowLibrary ragflowLibrary = new RagflowLibrary();
        ragflowLibrary.setCertNo(sysUser.getUserNum());
        RagflowLibrary libraryInfo = knowledgeBaseService.getInfoByCustInfo(ragflowLibrary);
        if(libraryInfo==null || StringUtils.isEmpty(libraryInfo.getLibraryId())){
            ragflowLibrary.setLibraryName(sysUser.getUserNum());
            ragflowLibrary.setCertNo(sysUser.getUserNum());
            ragflowLibrary.setPermissionType("02");
            ragflowLibrary.setLanguages("Chinese");
            try{
                /*保存知识库 */
                ragflowLibrary=knowledgeBaseService.saveLibrary(ragflowLibrary);
            }catch(Exception e){
                throw new RuntimeException(e);
            }
        }else{
            ragflowLibrary = libraryInfo;

        }
        RagFlowDocument document = new RagFlowDocument();
        document.setLibraryId(ragflowLibrary.getLibraryId());
        Map<String,Object> resMap = knowledgeBaseService.uploadAndParse(document.getLibraryId(),file,hsr);
        if(resMap==null){
            res.setStatus(ResponseVO.ERROR);
            res.setDescription("调用上传文档接口返回异常");
            return res;
        }
        int code = MapUtils.getIntValue(resMap,"code");
        if(code!=RAGFlowOK){
            String message = MapUtils.getString(resMap,"message");
            res.setStatus(ResponseVO.ERROR);
            res.setDescription("附件上传失败："+message);
            return res;
        }
        String mapStr = JSON.toJSONString(resMap);
        JSONObject resJson = JSON.parseObject(mapStr);
        JSONArray data = resJson.getJSONArray("data");
        if(data==null || data.size()<=0){
            res.setStatus(ResponseVO.ERROR);
            res.setDescription("附件上传失败：无数据返回");
            return res;
        }
        RagFlowDocument ragFlowDocument = new RagFlowDocument();
        ragFlowDocument.setLibraryId(ragflowLibrary.getLibraryId());
        List<RagFlowDocument> oldDocumentList = documentMapper.findDocumentByLibraryId(ragFlowDocument);
        String userName = sysUser.getLoginName();
        List<RagFlowDocument> newDocumentList = new ArrayList<>();
        List<String> documentIds = new ArrayList<>();
        for(Object item: data){
            document.preInsert(userName);
            String itemStr = JSON.toJSONString(item);
            Map<String,Object> map = JSON.parseObject(itemStr,Map.class);
            document.setTitle(MapUtils.getString(map,"name"));
            document.setDocId(MapUtils.getString(map,"id"));

            /*为解析 */
            document.setState(false);
            document.setLibraryId(MapUtils.getString(map, "dataset_id"));
            documentIds.add(document.getDocId());
            documentList.add(document);

        }
        documentMapper.insertBatch(newDocumentList);
        if(CollectionUtils.isNotEmpty(oldDocumentList)){
            List<String> docIds = oldDocumentList.stream().map(RagFlowDocument::getDocId).collect(Collectors.toList());
            knowledgeBaseService.deleteDocument(docIds,libraryInfo.getLibraryId());
        }

        int parsingCode = knowledgeBaseService.fileParse(documentIds,ragflowLibrary.getLibraryId());
        if(parsingCode!=RAGFlowOK){
            res.setStatus(ResponseVO.ERROR);
            res.setDescription("附件解析失败");
        }
        chatAssistant.setLibraryId(chatAssistant.getLibraryId()+","+ragflowLibrary.getLibraryId());

        res.setData(documentList.get(0));
        res.setStatus(ResponseVO.OK);
        return res;
                
            
    }

    @Override
    public ResponseVO updataChatAssistantLib(ChatAssistant chatAssistant) {
        ResponseVO res = new ResponseVO();
        SysUser sysUser = commonUtils.getCurrLoginUser();
        if(sysUser==null){
            res.setDescription("未登录");
            res.setStatus(ResponseVO.ERROR);
            return res;
        }
        RagflowLibrary ragflowLibrary = new RagflowLibrary();
        ragflowLibrary.setCertNo(sysUser.getUserNum());
        ragflowLibrary = ragflowLibraryMapper.getInfoByCustInfo(ragflowLibrary);
        if(regflowLibrary==null){
            return res;
        }

        chatAssistant = chatAssistantMapper.getInfoById(chatAssistant);
        if(chatAssistant.getLibraryId().contains(ragflowLibrary.getLibraryId())){
            res.setStatus(ResponseVO.OK);
            return res;
        }
        chatAssistant.setLibraryId(chatAssistant.getLibraryId()+","+ragflowLibrary.getLibraryId());
        Map<String,Object> mapRes = createChatAssistant(chatAssistant);
        int code = MapUtils.getIntValue(mapRes,"code");
        if(code!=RAGFlowOK){
            String message = MapUtils.getString(mapRes,"message");
            log.error("附件添加失败{}",message);
            res.setStatus(ResponseVO.ERROR);
            res.setDescription("更新助手选择的知识库失败："+message);
            return res;
        }
        res.setStatus(ResponseVO.OK);
        return res;
    }
    @Autowired
    private WpsExportUtil wpsExportUtil;


    @Override
    public void exportChatFile(ChatRecordVo chatRecordVo, HttpServletResopnse hsq, MultipartHttpServletRequest req) {
        JSONArray resSessionArr = null;
        List<ChatSessions> contentVoList = new ArrayList<>();
        contentVoList=chatRecordVo.getChatRecordList();
        
        String templateName = "chat_record.xlsx";

        if(CollectionUtils.isNotEmpty(contentVoList)){
            Map<String,Object> map = new HashMap<>();
            map.put("messages",contentVoList);
            try{
                switch (chatRecordVo.getType()){
                    case "word":
                        wpsExportUtil.exportWord("exportWord.ftl","chatRecordExport",hsq);
                    case "pdf":
                        wpsExportUtil.exportWord("exportWord.ftl","chatRecordExport",hsq);
                    case "xlsx":
                        wpsExportUtil.exportWord("exportWord.ftl","chatRecordExport",hsq);
                    default:
                        templateName = "exportWord.ftl";
                }
            }catch(Exception e){
                throw new RuntimeException(e);
            
            }catch(TemplateException e){
                throw new RuntimeException(e);
            }catch(Exception e){
                throw new RuntimeException(e);
            }
        }

    }

    @Override
    public List<Object> relatedQuestions(ChatSessions chatSessions) {
        Map<String,Object> mapReq = new HashMap<>();
        mapReq.put("question",chatSessions.getQuestion());
        String url = ragFlowConfig.getBaseUrl() + RagflowApi.related_questions;
        Map<String,Object> mapRes = this.requestRagFlowApi(mapReq,url,HttpMethod.POST);
        if(mapRes==null){
            throw new RuntimeException("调用相似问题查询接口返回异常");
        }
        int code = MapUtils.getIntValue(mapRes,"code");
        if(code!=RAGFlowOK){
            String message = MapUtils.getString(mapRes,"message");
            throw new RuntimeException(message);
        }
        Object obj = mapRes.get("data");
        String objStr = JSON.toJSONString(obj);
        List<Object> list = JSON.parseArray(objStr);
        return list;
    }


    private void exportWithExcel(List<ChatContentVo> contentVoList, HttpServletResponse res) {
        //声明一个工作簿
        HSSFWorkbook workbook = new HSSFWorkbook();
        //设置这些样式
        HSSFCellStyle style = workbook.createCellStyle();
        style.setFillForegroundColor(IndexedColors.LIGHT_BLUE.index);
        style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        //设置字体
        HSSFFont font = workbook.createFont();
        font.setColor(IndexedColors.BLUE_GREY.index);
        font.setFontHeightInPoints((short)10);
        style.setFont(font);

        //生成class类
        HSSFSheet sheet = workbook.createSheet("sheet");
        //产生表格标题
        HSSFRow row = sheet.createRow(0);
        String headers[] = {"角色","内容"};
        int rowIndex = 0;
        for(int i = 0; i < headers.length; i++){
            HSSFCell cell = row.createCell(i);
            cell.setCellStyle(style);
            cell.setCellValue(new HSSFRichTextString(headers[i]));

        }
            for(ChatContentVo item : contentVoList){
                row = sheet.createRow(rowIndex++);
                HSSFCell cell = row.createCell(0);
                if("user".equals(item.getRole())){
                    cell.setCellValue("用户");
                }else{
                    cell.setCellValue("信贷小助手");
                }

                cell = row.createCell(1);
                cell.setCellValue(item.getContent());




            }
            res.setHeader("Content-Disposition", "attachment; filename=chatRecordExport.xlsx");
            if(null == workbook){
                workbook = new HSSFWorkbook();

            }
            OutputStream os = null;
            try{
                os = res.getOutputStream();
                workbook.write(os);
            }catch(Exception e){
                throw new RuntimeException(e);
            }finally{
                if(workbook!=null){
                    try{
                        workbook.close();
                    }catch(Exception e){
                        throw new RuntimeException(e);
                    }
                }
                if(os!=null){
                    try{
                        os.close();
                    }catch(Exception e){
                        throw new RuntimeException(e);
                    }
                }
            }
    }

    private JSONArray getSessionById(ChatRecordVo chatRecordVo) {
        ChatAssistant chatAssistant = new ChatAssistant();
        chatAssistant.setId(chatRecordVo.getChatId());
        chatAssistant = chatAssistantMapper.getInfoById(chatAssistant);
        SysUser sysUser = commonUtils.getCurrLoginUser();
        Map<String,Object> mapReq = new HashMap<>();
        mapReq.put("user_id",sysUser.getUserNum());
        mapReq.put("id",chatAssistant.getAssistantId());
        String url = ragFlowConfig.getBaseUrl() + RagflowApi.managementChatAssistant+"/"+chatAssistant.getAssistantId()+"/sessions";
        Map<String,Object> mapRes = this.requestRagFlowApi(mapReq,url,HttpMethod.GET);
        if(mapRes==null){
            throw new RuntimeException("调用获取会话接口返回异常");
        }
        int code = MapUtils.getIntValue(mapRes,"code");
        if(code!=RAGFlowOK){
            String message = MapUtils.getString(mapRes,"message");
            throw new RuntimeException(message);
        }
        Object obj = mapRes.get("data");
        String dataStr = JSON.toJSONString(obj);
        return JSONArray.parseArray(dataStr);
    }

    private Flux<String> processStream(Flux<DataBuffer> dataBufferFlux) {
        return dataBufferFlux
                //使用字节流处理
                .transform(DataBufferUtils::join)
                .map(buffer -> {
                    byte[] bytes = new byte[buffer.readableByteCount()];
                    buffer.read(bytes);
                    DataBufferUtils.release(buffer);
                    String content = null;
                    try{
                        content = new String(bytes,"UTF-8");
                    }catch(UnsupportedEncodingException e){
                        e.printStackTrace();
                    }
                    return content;
                })
                //按SSE事件边界，防止粘包
                .flatMap(content -> Flux.fromArray(content.split("\n\n")))
                //过滤掉空字符串
                .filter(event -> !event.trim().isEmpty())
                //规范SSE事件格式
                .map(event -> {
                    String trimmed = event.trim();
                    if(trimmed.startsWith("data:")){
                        trimmed = trimmed.replaceFirst("data:","").trim();
                    }
                    return trimmed;
                })
                .filter(event -> !event.startsWith("data"))
    }

    public ChatSessions saveOrUpdataSessions(ChatSessions param) {
        String userNum = param.getCreateBy();
        if(StringUtils.isEmpty(userNum)){
            userNum = commonUtils.getCurrLoginUser().getUserNum();
        }
        Map<String,Object> mapRes = new HashMap<>();
        Map<String,Object> mapReq = new HashMap<>();
        mapReq.put("name",param.getSessionName());
        mapReq.put("user_id",userNum);
        ChatAssistant chatAssistant = new ChatAssistant();
        chatAssistant.setId(param.getChatId());
        chatAssistant = chatAssistantMapper.getInfoById(chatAssistant);
        if(StringUtil.isEmpty(param.getSessionId())){
            mapReq.put("name",StringUtil.isEmpty(param.getSessionsName())?"默认会话":param.getSessionsName());
            String url = ragFlowConfig.getBaseUrl() + RagflowApi.managementChatAssistant+"/"+chatAssistant.getAssistantId()+"/sessions";
            mapRes = requestChatSessionApi(mapReq,url,HttpMethod.POST);

        }else{
            String url = ragFlowConfig.getBaseUrl() + RagflowApi.managementChatAssistant+"/"+chatAssistant.getAssistantId()+"/sessions/"+param.getSessionId();
            mapRes = requestChatSessionApi(mapReq,url,HttpMethod.PUT);
        }
        if(mapRes==null){
            throw new RuntimeException("调用保存会话接口返回异常");
        }
        int code = MapUtils.getIntValue(mapRes,"code");
        if(code!=RAGFlowOK){
            String message = MapUtils.getString(mapRes,"message");
            throw new RuntimeException(message);
        }
        Object obj = mapRes.get("data");
        String objStr = JSON.toJSONString(obj);
        Map<String,Object> resData = JSON.parseObject(objStr);
        ChatSessions chatSessions = new ChatSessions();
        if(StringUtil.isEmpty(param.getSessionId())){
            chatSessions.setChatId(MapUtils.getString(resData,"chat_id"));
            chatSessions.setMessages(resData.get("messages"));
            chatSessions.setSessionId(MapUtils.getString(resData,"id"));
            chatSessions.setSessionName(MapUtils.getString(resData,"name"));

        }else{
            chatSessions.param;
        }
        return chatSessions;

    }

    private Map<String,Object> requestChatSessionApi(Map<String,Object> mapReq, String url, HttpMethod httpMethod) {
        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Type","application/json; charset=UTF-8");
        headers.add("Authorization","Bearer "+ragFlowConfig.getApiKey());
        headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
        Map<String,Object> mapRes = new HashMap<>();
        HttpEntity<Map<String,Object>> HttpEntity = new HttpEntity<>(mapReq,headers);
        ResponseEntity<HashMap> result = restTemplate.exchange(url,httpMethod,HttpEntity,HashMap.class);
        int status = result.getStatusCodeValue();
        if(status==ResponseVO.ERROR){
            throw new RuntimeException("接口嗲用异常");

        }
        mapRes = result.getBody();
        return mapRes;
    }

    private Map<String,Object> updateChatAssistant(ChatAssistant param) {
        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Type","application/json; charset=UTF-8");
        headers.add("Authorization","Bearer "+ragFlowConfig.getApiKey());
        headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
        Map<String,Object> mapReq = new HashMap<>();
        if(StringUtil.isNotEmpty(param.getLibraryId)){
            mapReq.put("dataset_id",param.getLibraryId().split(","));
        }
        mapReq.put("name",param.getAssistantName());
        mapReq.put("description",param.getDescription());
        HttpEntity<Map<String,Object>> HttpEntity = new HttpEntity<>(mapReq,headers);
        String url = ragFlowConfig.getBaseUrl() + RagflowApi.managementChatAssistant+"/"+param.getAssistantId();
        ResponseEntity<HashMap> result = restTemplate.exchange(url,HttpMethod.PUT,HttpEntity,HashMap.class);
        int status = result.getStatusCodeValue();
        if(status==ResponseVO.ERROR){
            throw new RuntimeException("接口嗲用异常");
        }
        Map<String,Object> mapRes = new HashMap<>();
        return mapRes;
        
        
    }

    private Map<String,Object> createChatAssistant(ChatAssistant param) {
        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Type","application/json; charset=UTF-8");
        headers.add("Authorization","Bearer "+ragFlowConfig.getApiKey());
        headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
        Map<String,Object> mapReq = new HashMap<>();


        mapReq.put("dataset_id",param.getLibraryId().split(","));
        mapReq.put("name",param.getAssistantName());
        mapReq.put("description",param.getDescription());
        mapReq.put("language",param.getLanguages());
        mapReq.put("prompt_config",param.getPromptConfig());
        HttpEntity<Map<String,Object>> HttpEntity = new HttpEntity<>(mapReq,headers);
        String url = ragFlowConfig.getBaseUrl() + RagflowApi.managementChatAssistant;
        ResponseEntity<HashMap> result = restTemplate.exchange(url,HttpMethod.POST,HttpEntity,HashMap.class);
        int status = result.getStatusCodeValue();
        if(status==ResponseVO.ERROR){
            throw new RuntimeException("接口嗲用异常");
        }
        Map<String,Object> mapRes = new HashMap<>();
        return mapRes;
    }
}
